import time
from typing import Set
from loguru import logger
from typing import List
from sqlalchemy.orm import Session
from loguru import logger
from models.NewInfoPush import NewInfoPush
from Util.MailUtil import send_mail
from config.Database import get_db
from schemas.NewInfoPush import NewInfoPushUpdate
from schemas.Page import PageCreate
from services.ActivityNotStartCache import ActivityNotStartCache
from services.NewInfoPushService import NewInfoPushService

# 存储已知活动ID的集合
known_activity_ids: Set[int] = set()
activity_not_start_cache_instance = None
# 添加一个标志，用于标识是否是首次运行
is_first_run = True

async def check_new_activities():
    """
    检查新活动并发送邮件通知
    
    此函数会：
    1. 从缓存中获取所有未开始的活动
    2. 检查是否有新的活动ID
    3. 如果有新活动，向所有订阅用户发送邮件通知
    4. 更新用户的推送计数
    """
    logger.info(f"check_new_activities 开始检查新活动：当前时间 {time.strftime('%Y-%m-%d %H:%M:%S')}")
    
    # 获取数据库会话
    db = next(get_db())
    try:
        # 初始化或获取活动缓存实例
        global activity_not_start_cache_instance
        if activity_not_start_cache_instance is None:
            logger.info("初始化活动缓存实例")
            page = PageCreate(pageNum=1, pageSize=99, sortType=1, status=4)
            activity_not_start_cache_instance = ActivityNotStartCache(db, page)


        # 获取所有未开始的活动
        activities = activity_not_start_cache_instance.get_activities()
        
        # 提取活动ID
        current_activity_ids = {activity.id for activity in activities}
        
        # 找出新的活动ID
        global known_activity_ids, is_first_run
        new_activity_ids = current_activity_ids - known_activity_ids

        # 更新已知活动ID集合
        known_activity_ids.update(new_activity_ids)
        logger.info(f"已更新已知活动ID集合,当前共有 {len(known_activity_ids)} 个活动")

        # 如果是首次运行，只更新已知活动ID集合，不发送通知
        if is_first_run:
            logger.info("首次运行，不发送新活动通知")
            is_first_run = False
            return

        if not new_activity_ids:
            logger.info("没有发现新活动")
            return
        
        logger.info(f"发现 {len(new_activity_ids)} 个新活动: {new_activity_ids}")
        
        # 获取所有需要推送的用户
        new_info_push_service = NewInfoPushService()
        users_to_notify = new_info_push_service.get_all(db)
        
        # 筛选出count大于0的用户
        users_to_notify = [user for user in users_to_notify if user.count > 0]
        
        if not users_to_notify:
            logger.info("没有需要通知的用户")
            return
        
        # 构建新活动信息
        new_activities = [activity for activity in activities if activity.id in new_activity_ids]
        
        # 发送邮件通知
        await send_activity_notifications(users_to_notify, new_activities, new_info_push_service, db)
        
    except Exception as e:
        logger.error(f"检查新活动时出错: {str(e)}", exc_info=True)
    finally:
        # 确保关闭数据库会话
        db.close()



def format_timestamp(timestamp_ms):
    # 确保时间戳是数值类型
    if isinstance(timestamp_ms, str):
        return timestamp_ms
    # 将毫秒时间戳转为格式化字符串
    return time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(timestamp_ms / 1000))


async def send_activity_notifications(users: List[NewInfoPush], activities: List, service, db: Session):
    """
    向用户发送新活动通知邮件

    Args:
        users: 需要通知的用户列表
        activities: 新活动列表
        service: NewInfoPushService实例
        db: 数据库会话
    """
    logger.info(f"需要通知 {len(users)} 个用户")

    # 为每个用户发送邮件
    for user in users:
        try:
            # 构建邮件内容
            email_subject = f"第二课堂新活动通知-发现{len(activities)}个新活动"
            email_content = "尊敬的用户，\n\n以下是最新发布的第二课堂活动：\n\n"
            # TODO 这里的时间是None
            for activity in activities:
                start_time = format_timestamp(activity.startTime)
                end_time = format_timestamp(activity.endTime)
                enroll_start = format_timestamp(activity.enrollStartTime)
                enroll_end = format_timestamp(activity.enrollEndTime)

                email_content += f"- {activity.name}\n"
                email_content += f"  活动时间: {start_time} 至 \n{end_time}\n"
                email_content += f"  报名时间: {enroll_start} 至 \n{enroll_end}\n\n"

            email_content += "您可以访问https://yirc99.cn/activity系统查看详情并预约自动报名参加。\n\n"
            email_content += "如需取消订阅，请将推送邮件中的推送计数设置为0。"

            # 发送邮件
            send_mail(user.email, email_subject, email_content)
            logger.info(f"已向用户 {user.email} 发送新活动通知")

            # 更新用户的推送计数
            user.count -= 1
            update_data = NewInfoPushUpdate(count=user.count)
            service.update(db, user.id, update_data)

        except Exception as e:
            logger.error(f"向用户 {user.email} 发送邮件失败: {str(e)}")


